﻿/*
 * Copyright 2010 Marc Cesarine

 * This file is part of Ssh Commander.

 * Ssh Commander is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * Ssh Commander is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with Ssh Commander.  If not, see <http://www.gnu.org/licenses/>.
 */

using System.IO;
using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.HSSF.Util;
using System.Collections.Generic;

namespace SshCommander
{
    class Excel
    {
        #region variables

        private HSSFWorkbook hssfworkbook_v;
        private HSSFSheet hssfsheet_v;
        private List<ColumnHeader> ColumnHeadersList_v;

        #endregion

        #region constructor

        public Excel()
        {
            ColumnHeadersList_v = new List<ColumnHeader>();
        }

        #endregion

        #region methods

        /// <summary>
        /// Open existing excel file
        /// </summary>
        /// <param name="filestream">stream of file to open</param>
        public void OpenFile(Stream filestream)
        {
            hssfworkbook_v = new HSSFWorkbook(filestream);
        }

        /// <summary>
        /// Create a new excel file
        /// </summary>
        public void CreateFile()
        {
            hssfworkbook_v = new HSSFWorkbook();
        }

        /// <summary>
        /// Set excel file information
        /// </summary>
        /// <param name="company">company name displayed in file information</param>
        /// <param name="subject">subject displayed in file information</param>
        public void SetFileInfo(string company, string subject)
        {
            // Create a entry of DocumentSummaryInformation
            DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
            dsi.Company = company;
            hssfworkbook_v.DocumentSummaryInformation = dsi;

            // Create a entry of SummaryInformation
            SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
            si.Subject = subject;
            hssfworkbook_v.SummaryInformation = si;
        }

        /// <summary>
        /// Select sheet to be the active one
        /// </summary>
        /// <param name="sheetname">name of sheet to activate</param>
        public void SelectSheet(string sheetname)
        {
            hssfsheet_v = hssfworkbook_v.GetSheet(sheetname);
        }

        /// <summary>
        /// Modify color value with custom one
        /// </summary>
        /// <param name="origincolorindex">index of original color</param>
        /// <param name="redvalue">red value (RGB)</param>
        /// <param name="greenvalue">green value (RGB)</param>
        /// <param name="bluevalue">blue value (RGB)</param>
        public void SetCustomColor(short origincolorindex, byte redvalue, byte greenvalue, byte bluevalue)
        {
            HSSFPalette palette = hssfworkbook_v.GetCustomPalette();
            palette.SetColorAtIndex(origincolorindex, redvalue, greenvalue, bluevalue);
        }

        /// <summary>
        /// Create a new style in excel file
        /// </summary>
        /// <returns>Style which have been created</returns>
        public HSSFCellStyle CreateStyle()
        {
            return hssfworkbook_v.CreateCellStyle();
        }

        /// <summary>
        /// Create new font in excel file
        /// </summary>
        /// <returns>Font which has been created</returns>
        public HSSFFont CreateFont()
        {
            return hssfworkbook_v.CreateFont();
        }

        /// <summary>
        /// Save actual working file
        /// </summary>
        /// <param name="filename">full path and file name where the file will be saved</param>
        public void SaveFile(string filename)
        {
            FileStream file = new FileStream(filename, FileMode.Create);
            hssfworkbook_v.Write(file);
            file.Close();
        }

        /// <summary>
        /// Select cell in actual sheet
        /// </summary>
        /// <param name="column">column index of cell</param>
        /// <param name="row">row index of cell</param>
        /// <returns></returns>
        public HSSFCell GetCell(int column, int row)
        {
            HSSFRow selectedrow = hssfsheet_v.GetRow(row);
            HSSFCell selectedcell = null;

            if (selectedrow == null)
            {
                selectedrow = hssfsheet_v.CreateRow(row);
                
            }

            selectedcell = selectedrow.GetCell(column);

            if(selectedcell == null)
            {
                selectedcell = selectedrow.CreateCell(column);
            }

            return selectedcell;
        }

        /// <summary>
        /// Merge group of cells in actual sheet
        /// </summary>
        /// <param name="fromcolumn">column index of top left cell</param>
        /// <param name="fromrow">row index of top left cell</param>
        /// <param name="tocolumn">column index of bottom right cell</param>
        /// <param name="torow">row index of bottom right cell</param>
        public void MergeCells(int fromcolumn, int fromrow, int tocolumn, int torow)
        {
            hssfsheet_v.AddMergedRegion(new Region(fromrow, fromcolumn, torow, tocolumn));
        }

        /// <summary>
        /// Add a header in list of excel file
        /// </summary>
        /// <param name="headerlabel">label of header to add</param>
        /// <param name="columnid">column index of header to add</param>
        public void AddHeader(string headerlabel, int columnid)
        {
            if (headerlabel != "")
            {
                ColumnHeadersList_v.Add(new ColumnHeader(headerlabel, columnid));
            }
        }

        /// <summary>
        /// Get header index of an existing header in actual file
        /// </summary>
        /// <param name="headerlabel">label of header</param>
        /// <returns>column index of header</returns>
        public int GetHeaderID(string headerlabel)
        {
            int Result = -1;

            if (headerlabel != "")
            {
                bool Found = false;
                int i = 0;

                while ((!Found) && (i < ColumnHeadersList_v.Count))
                {
                    if (ColumnHeadersList_v[i].label_v == headerlabel)
                    {
                        Found = true;
                        Result = ColumnHeadersList_v[i].columnid_v;
                    }
                    else
                    {
                        i++;
                    }
                }
            }

            return Result;
        }

        #endregion
    }
}

public struct ColumnHeader
{
    public string label_v;
    public int columnid_v;

    public ColumnHeader(string label, int columnid)
    {
        label_v = label;
        columnid_v = columnid;
    }
}